In early microprocessors, instruction execution was “atomic”—the processor fetched an instruction and completely executed it, then fetched another and executed it, etc. Most modern microprocessors execute instructions in several steps rather than atomically. This series of steps is called the “instruction execution pipeline”, or just the “pipeline”. Typically a pipeline will consist of several phases, consisting of steps to read the instruction from memory, decode the instruction, read the values to be operated on, perform the operation, and write the result to some kind of storage. This is called a “pipeline” because a processor can have several instructions executing at the same time in different phases, ie “in the pipeline”. In this mode of operation, the processor can be fetching an instruction while it is decoding the previous instruction, while it is reading input values for an earlier instruction, etc. By overlapping the execution of instructions, we increase the rate at which the processor can execute instructions.
An implication of pipelining is that an instruction which is in the “read inputs” phase may need a value produced by an earlier instruction, but the “write” of that value hasn't happened yet. There are generally two ways to deal with this situation: either the processor must look for these situations and insert the appropriate stalls in the pipeline, or the programmer must arrange the instructions such that this never happens by scheduling the dependent instructions far enough apart so that the situation doesn't arise. The former solution is generally called a “protected” pipeline, and the later solution is called an “unprotected” pipeline. Almost all modern general purpose architectures implement “protected” pipelines.
Protected pipelines have the advantage that they allow the CPU designers to deepen the pipeline in subsequent generations of the processor while still properly executing legacy code. However, this requires a great deal of logic to detect situations where they must insert delays in the pipeline.
Unprotected pipelines have the advantage that they require little/no hardware to insert delays. The programmer or compiler is responsible for scheduling instructions such that instructions complete before their results are needed by subsequent instructions. Unprotected pipelines allow the use of “multiple-assignment” code, in which multiple writes to a particular register can be in the pipeline simultaneously. This is a very low-cost, low-complexity alternative to register renaming, and is critical for high performance low power digital signal processing (DSP) applications.
Existing processors are designed to have either protected or unprotected behavior.